[Chapter 12] 12.2 The File Form of Class
Author: Bryan Costales & Eric Allman
Date: 1999-01-06T18:36:55Z

#

| Chapter 12 Class |

## 12.2 The File Form of Class

It is not always possible or convenient to list the values for a class directly in the configuration file. Sometimes it might be better to store values in files. Examples of this might be the following:

- The names of hosts that are connected to the local machine via UUCP. At some sites, such connections are created and removed often, and it is undesirable to be constantly changing the configuration file.

- The names of hosts that are being moved from one location to another. During a move, it is better to modify an external file while each hostname is changed and then to modify the configuration file after all the moves have been done.

- The alternative names for a machine may vary from machine to machine, yet a single configuration file may be shared among them. When such a boilerplate configuration file is centrally maintained (and distributed with rdist(1), for example), names that indicate the specialty roles of a machine should be external to that file.

The client.cf file lists two additional names for the local host in the class `w`:

>     Cw localhost printer1          # My other names.

To make this configuration file more general, it would be better to store the host-specific name (`printer1`) in a separate file. To externalize words for a class list, you use the `F` configuration command. That command looks like this:

>     Fw/path

The `F` must begin a line. This tells sendmail that this is a class definition, just like the `C` command that we just illustrated. The name of the class (here `w`) must immediately follow the `F` with no intervening space. If the class name is multicharacter, it must be enclosed in curly braces. Optional space may separate the class name from the `/path`. With the `C` command, a list of words follows the name on the same line, but with the `F` command, the name of a file follows. `/path` is the full pathname of a file. For demonstration purposes we will name that file /etc/sendmail.cw. [1]

> [1] This is the path recommended by V8.7 and above sendmail.

Edit the client.cf file and make two changes. Delete the name `printer1` from the `C` line and add a new `F` line:

>                  remove printer1

>     Cw localhost                   # My other names.
>     Fw/etc/sendmail.cw             # A file of other names        new

The first class definition starts with the letter `C` and tells sendmail to add the name `localhost` to the list of words in the class `w`. The second line tells sendmail to read the file named /etc/sendmail.cw and to add the words in that file to the class `w`. Note that the name `w` is the same for each line. The `C` and `F` commands differ only in where the words are taken from.

Now run sendmail and notice what happens when the file /etc/sendmail.cw doesn't exist:

>     % ./sendmail -Cclient.cf -bt
>     client.cf: line 7: fileclass: cannot open /etc/sendmail.cw: No such file or directory
>     ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
>     Enter <ruleset> <address>
>     >

As you would expect, sendmail prints an error message when it fails to find the file. But as you might not expect, sendmail prints the error warning and continues to run.

Because we are developing a generic configuration file, one that can be shared among many machines, we would prefer not to have an error printed if the file doesn't exist. We can suppress the error message by adding a `-o` (for optional) switch to the `F` configuration command:

>     Fw -o /etc/sendmail.cw         # A file of other names

>        new

Now run sendmail again and notice that the error message is gone:

>     % ./sendmail -Cclient.cf -bt
>     ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)

>     Enter <ruleset> <address>
>     >

But we still want the name `printer1` to be recognized as local. To do that, we need to either put it back into the `C` line that we just removed it from or put it into the file that doesn't exist yet, the /etc/sendmail.cw file.

Create and edit the file /etc/sendmail.cw. If you lack write permission, create a file that you are permitted to write to (such as /usr/tmp/sendmail.cw) and use it in the following examples and in the client.cf file. Put this hostname into that file:

>     printer1

The next time you run sendmail, it reads this file and adds each word it sees to the class `w`. Run sendmail in rule-testing mode again and verify that for yourself:

>     % ./sendmail -Cclient.cf -bt
>     ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
>     Enter <ruleset> <address>
>     > $=w
>     here.us.edu
>     localhost
>     here
>     [123.45.67.8]
>     printer1

Success! Now add some more names to the sendmail.cw file. We will use bogus names just for demonstration purposes:

>              add

>     printer1 bogus
>     fake                add

Run sendmail again and notice that the name `bogus` is missing:

>     % ./sendmail -Cclient.cf -bt
>     ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
>     Enter <ruleset> <address>
>     > $=w
>     here.us.edu
>     fake
>     localhost
>     here
>     [123.45.67.8]
>     printer1

Why is `bogus` missing? To answer this question, leap ahead to Section 32.1, "Class Configuration Commands". But for now, just assume that there may be only one word per line.

12.1 The Class Command |  | 12.3 Things to Try